/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 *
 */

import { expect } from '@jest/globals';
import * as fs from 'fs';
import * as fse from 'fs-extra';
import { readdirSync } from 'fs-extra';
import * as path from 'path';
import { resolve } from 'path';

import { CompileModeEnum } from '../../src/enum/compile-mode-enum';

import { addOhosTestDependency, initByStageEmptyApp, initExecuteCommand, runHvigor } from './common/common';
import { ModuleBuildProfileModifier } from './common/modifier/module-build-profile-modifier';
import { Probes } from './common/probes';

describe('ohosTest test', () => {
  test.concurrent('test ohosTest - Stage assembleHap', async () => {
    await initByStageEmptyApp({
      prepare: addOhosTestDependency,
      cb: async (dir) => {
        const entryBuildProfile = new ModuleBuildProfileModifier(dir, 'entry');
        entryBuildProfile.setCompileMode(CompileModeEnum.JS_BUNDLE)
          .outputSync();
        const commands = initExecuteCommand({
          mode: 'module',
          product: 'default',
          module: 'entry@ohosTest',
          tasks: 'assembleHap',
        });
        const result = runHvigor(dir, commands);

        // run successful
        expect(result.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();

        if (!fse.existsSync(path.resolve(dir, 'entry', 'src', 'ohosTest'))) {
          return;
        }

        const probe = new Probes(dir, resolve(dir, 'entry'), 'ohosTest');

        const stageIntermediateRes = readdirSync(probe.getIntermediatesRes());
        expect(stageIntermediateRes.sort()).toEqual([
          'resources',
          'ids_map',
          'module.json',
          'resConfig.json',
          'resources.index',
          'ResourceTable.txt'
        ].sort());

        const stageBuildOutput = readdirSync(probe.getModuleBuildOutputPath());
        expect(stageBuildOutput.sort()).toEqual([
          'entry-ohosTest-unsigned.hap',
          'entry-ohosTest-signed.hap',
          'pack.info'
        ].sort());
      },
      runNpmInstall: true
    });
  });

  test.concurrent('test ohosTest - product ohosTest config assembleApp', async () => {
    await initByStageEmptyApp(async (projectRoot) => {
      const ohosTestDir = path.resolve(projectRoot, 'entry/src/ohosTest');
      const profile = path.resolve(projectRoot, 'entry/build-profile.json5');
      fs.writeFileSync(profile, '{\n' +
        '  "apiType": \'stageMode\',\n' +
        '  "buildOption": {\n' +
        '  },\n' +
        '  "targets": [\n' +
        '    {\n' +
        '      "name": "default",\n' +
        '      "runtimeOS":"HarmonyOS"\n' +
        '    },\n' +
        '    {\n' +
        '      "name": "ohosTest",\n' +
        '    }\n' +
        '  ]\n' +
        '}');
      fse.rmSync(ohosTestDir, { recursive: true });
      const commands = initExecuteCommand({
        mode: 'project',
        product: 'default',
        tasks: 'assembleApp',
        log: 'info'
      });
      const result = runHvigor(projectRoot, commands);
      expect(result.stdout).toContain('BUILD SUCCESSFUL');

      const commands2 = initExecuteCommand({
        mode: 'module',
        product: 'default',
        module: 'entry@ohosTest',
        tasks: 'assembleHap',
      });
      const result2 = runHvigor(projectRoot, commands2);
      expect(result2.stderr)
        .toContain('/main/ohosTest\' directory cannot be found');
      expect(result2.stderr)
        .toContain('Alternatively, make sure the module directory contains the');

    });
  });

  test.concurrent('test ohosTest compile ArkTs', async () => {
    await initByStageEmptyApp({
      prepare: addOhosTestDependency,
      cb: async (projectRoot) => {
        const profile = path.resolve(projectRoot, 'entry/build-profile.json5');
        fs.writeFileSync(profile, '{\n' +
          '  "apiType": \'stageMode\',\n' +
          '  "buildOption": {\n' +
          '  },\n' +
          '  "targets": [\n' +
          '    {\n' +
          '      "name": "default"\n' +
          '    },\n' +
          '    {\n' +
          '      "name": "ohosTest",\n' +
          '    }\n' +
          '  ]\n' +
          '}');
        const commands = initExecuteCommand({
          mode: 'module',
          product: 'default',
          module: 'entry@ohosTest',
          tasks: 'assembleHap',
        });
        const result = runHvigor(projectRoot, commands);
        expect(result.stdout).toContain('Finished :entry:ohosTest@OhosTestCompileArkTS...');
        expect(result.stdout).toContain('BUILD SUCCESSFUL');

        // 第二次执行 expect UpToDate
        const result2 = runHvigor(projectRoot, commands);
        expect(result2.stdout).toContain('UP-TO-DATE :entry:ohosTest@OhosTestCompileArkTS...');
        expect(result2.stdout).toContain('BUILD SUCCESSFUL');

        const mainIndexFilePath = path.resolve(projectRoot,
          'entry/src/main/ets/pages2/index.ets');

        const data = '@Entry\n' +
          '@Component\n' +
          'struct Page {\n' +
          '  @State message: string = \'Hello World\'\n' +
          '  build() {\n' +
          '  }\n' +
          '}\n' +
          'export function test() {\n' +
          '  var a = 1112;\n' +
          '  var b = 2223;\n' +
          '  var c = 3334;\n' +
          '  var c2 = 4445;\n' +
          '  test2();\n' +
          '  var d = 4446;\n' +
          '}\n' +
          'export function test2() {\n' +
          '  var aaa = 1233;\n' +
          '  var bbb = 2343;\n' +
          '  var ccc = 3453;\n' +
          '}\n';
        fs.writeFileSync(mainIndexFilePath, data);

        const result3 = runHvigor(projectRoot, commands);
        expect(result3.stdout).toContain('Finished :entry:ohosTest@OhosTestCompileArkTS...');
        expect(result3.stdout).toContain('BUILD SUCCESSFUL');
      },
      runNpmInstall: true
    });
  });

});
